/*
 * Copyright (c) 2018-2023 北京华恒盛世科技有限公司
 * QUICKPOOL is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/

#ifndef QUICKPOOL_H
#define QUICKPOOL_H

#include <config.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include <syslog.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <netdb.h>
#include <fcntl.h>
#include <grp.h>
#include <ctype.h>
#include <dirent.h>
#include <time.h>
#include <zlib.h>
#include <termios.h>
#include <pwd.h>
#include <dlfcn.h>
#include <limits.h>
#include <pthread.h>
#include <poll.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <list.h>
#include <sys/epoll.h>
#include <sys/poll.h>
#include <rpc/types.h>
#include <rpc/xdr.h>

#include "xdrbase.h"

#ifdef REL_DATE
#define _QP_VERSION_ (_QUICKPOOL_PROJECT_", " REL_DATE"\n")
#else
#define _QP_VERSION_ (_QUICKPOOL_PROJECT_", " __DATE__"\n")
#endif

#define QP_XDR_VERSION 1

#define MAXNAMELEN              1024    /**< maximum length of name */
#define NUMBUILTIN              9       /**< default number of built-in resource */
#define MAXTYPES                128     /**< maximum of defined host type */
#define MAXMODELS               128     /**< maximum of defined host model */
#define MAXMESSAGELENGTH        10240   /**< maximum length of error message */
#define MAXVERSIONLEN           12      /**< maximum length of quickpoool version string */
#define MAX_ARGS                16      /**< maximum number of argument */

#define NICE_LEAST -40
#define NICE_MIDDLE 20

#define RESOURCE_FLAG_BUILTIN      0x01  /**< QuickPool builtin resource */
#define RESOURCE_FLAG_DYNAMIC      0x02  /**< resource value is dynamic. unrm report its value */
#define RESOURCE_FLAG_GLOBAL       0x04  /**< resource defined in all clusters */
#define RESOURCE_FLAG_SHARED       0x08  /**< resource is shared by some nodes */
#define RESOURCE_FLAG_RELEASE      0x10  /**< resource is releasable if job is suspended */
#define RESOURCE_FLAG_FREE_SLOT    0x20  /**< resource is sorted by free slots when schedule job */
#define RESOURCE_FLAG_MAX_JOB_SLOT 0x40  /**< resource is sorted by max job slots when schedule job */
#define RESOURCE_FLAG_CONSUMABLE   0x80  /**< resource is consumable, can be used in rusage section */
#define RESOURCE_FLAG_SHARED_ALL   0x100 /**< resource is shared by all the nodes */
#define RESOURCE_FLAG_DEFAULT_ALL  0x200 /**< resource is shared by every nodess */

#define REMOTE_MAXHOSTS 5
#define REMOTE_O_CREAT_DIR 04000
#define REMOTE_TASKPORT 0x04
#define REMOTE_STDERR   0x10

#define QUEUE_STATUS_OPEN         0x01
#define QUEUE_STATUS_ACTIVE       0x02
#define QUEUE_STATUS_RUN          0x04
#define QUEUE_STATUS_RUNWIN_CLOSE 0x20

#define QUEUE_POLICY_EXCLUSIVE       0x01
#define QUEUE_POLICY_ROUND_ROBIN     0x02
#define QUEUE_POLICY_PREEMPTIVE      0x04
#define QUEUE_POLICY_BACKFILL        0x08
#define QUEUE_POLICY_NO_HOST_TYPE    0x10
#define QUEUE_POLICY_IGNORE_DEADLINE 0x20
#define QUEUE_POLICY_CHKPNT          0x40
#define QUEUE_POLICY_RERUNNABLE      0x80
#define QUEUE_POLICY_FAIRSHARE       0x100
#define QUEUE_POLICY_OWNERSHIP       0x200
#define QUEUE_POLICY_MEM_RESERVE     0x400

#define DEFAULT_MAX_JOBID 999999
#define MAX_JOBID_LOW 999999
#define MAX_JOBID_HIGH 9999999

#define JGRP_NODE_JOB      1
#define JGRP_NODE_GROUP    2
#define JGRP_NODE_ARRAY    3

#ifndef JOBID_T
typedef long long int JOBID_T;
#endif

#define ONEMINUTE 60
#define ONEHOUR 60*ONEMINUTE
#define ONEDAY 24*ONEHOUR
#define ONEWEEK 7*ONEDAY

/* request code */
#define TO_TOP            1
#define TO_BOTTOM         2

#define REQUEUE_DONE   0x1
#define REQUEUE_EXIT   0x2
#define REQUEUE_RUN    0x4

#define ERROR_MEMORY               1
#define ERROR_NO_JOB               2
#define ERROR_NO_OUTPUT            3
#define ERROR_NO_JOBID             4
#define ERROR_NO_USER              5
#define ERROR_NO_HOST              6
#define ERROR_NO_MEMBER            7
#define ERROR_NO_QUEUE             8
#define ERROR_NO_HOST_GROUP        9
#define ERROR_NO_USER_GROUP       10
#define ERROR_NO_JOB_GROUP        11
#define ERROR_NO_RESOURCE         12
#define ERROR_NO_FILE             13
#define ERROR_NO_DEPENDENCY       15
#define ERROR_JOB_NOT_START       16
#define ERROR_JOB_STARTED         17
#define ERROR_JOB_FINISH          18
#define ERROR_JOB_NAME            19
#define ERROR_JOB_MODIFY          20
#define ERROR_JOB_REQUEUED        21
#define ERROR_JOB_RETRY           22
#define ERROR_JOB_CHKPNT          23
#define ERROR_MOD_JOB_NAME        24
#define ERROR_MOD_MIX_OPTS        25
#define ERROR_EXCLUSIVE           26
#define ERROR_MIGRATION           27
#define ERROR_HOST_DEFINED        28
#define ERROR_ZOMBIE_JOB          29
#define ERROR_DYNAMIC_HOST        30
#define ERROR_PERMISSION          31
#define ERROR_WRONG_MASTER        32
#define ERROR_QUEUE_CLOSED        33
#define ERROR_QUEUE_WINDOW        34
#define ERROR_QUEUE_USER          35
#define ERROR_QUEUE_HOST          36
#define ERROR_NUM_PROCESSOR       37
#define ERROR_MESSAGE             38
#define ERROR_FILE_FORMAT         39
#define ERROR_FORK_FAIL           40
#define ERROR_QUSER_SLOT_LIMIT    41
#define ERROR_USER_SLOT_LIMIT     42
#define ERROR_DEPEND_SYNTAX       43
#define ERROR_QUEUE_SLOT_LIMIT    44
#define ERROR_QNODE_SLOT_LIMIT    45
#define ERROR_OVER_LIMIT          46
#define ERROR_COMMUNICATE         47
#define ERROR_ARGUMENT            48
#define ERROR_TERMINATE_TIME      49
#define ERROR_SIGNAL_PENDING      50
#define ERROR_EOF                 51
#define ERROR_JS_INTERNAL         52
#define ERROR_JM_INTERNAL         53
#define ERROR_HOST_REBOOT         54
#define ERROR_XDR                 55
#define ERROR_SYS_CALL            56
#define ERROR_PARSE_VALUE         57
#define ERROR_PARSE_RESOURCE      58
#define ERROR_PARSE_FILTER        59
#define ERROR_PARSE_REQUIREMENT   60
#define ERROR_SUBEXEC_FILE        61
#define ERROR_CONNECTION          62
#define ERROR_OP_RETRY            63
#define ERROR_DAEMON_DOWN         64
#define ERROR_CONF_FATAL          65
#define ERROR_CONF_WARNING        66
#define ERROR_SUBMISSION_NODE     67
#define ERROR_LOCK_JOB            68
#define ERROR_REQUEUE_REQUEST     69
#define ERROR_JOB_HASDEPENDENCY   70
#define ERROR_JOB_GROUP_PATH      71
#define ERROR_JOB_GROUP_EXIST     72
#define ERROR_JOB_GROUP_HASCHILD  73
#define ERROR_JOB_GROUP_LIMIT     74
#define ERROR_JOB_ARRAY           75
#define ERROR_JOB_ARRAY_INDEX     76
#define ERROR_JOB_ARRAY_BIGINDEX  77
#define ERROR_JOBID_STRING        78
#define ERROR_USER_PRIORITY       79
#define ERROR_DEPEND_ARRAY_SIZE   80
#define ERROR_MULTIPLE_FIRST_NODE 81
#define ERROR_NG_FIRST_NODE       82
#define ERROR_OTHERS_FIRST_NODE   83
#define ERROR_REQUEUE_EXITCODE    84
#define ERROR_ROOT_SUBMIT         85
#define ERROR_SOCKETPAIR          86
#define ERROR_TASK_EXECUTION      87
#define ERROR_RECORD_TYPE         88

/* job status */
#define JOB_STATUS_PEND   0x01
#define JOB_STATUS_PSUSP  0x02
#define JOB_STATUS_RUN    0x04
#define JOB_STATUS_SSUSP  0x08
#define JOB_STATUS_USUSP  0x10
#define JOB_STATUS_EXIT   0x20
#define JOB_STATUS_DONE   0x40
#define JOB_STATUS_PDONE  0x80
#define JOB_STATUS_PERR   0x100
#define JOB_STATUS_UNKWN  0x10000

#define JOB_STATUS_VOID         0x00100000
#define JOB_STATUS_PREEMPT_WAIT 0x00400000
#define JOB_STATUS_KILL         0x00800000
#define JOB_STATUS_ZOMBIE       0x02000000
#define JOB_STATUS_PREJOB       0x04000000
#define JOB_STATUS_SIGNAL       0x08000000
#define JOB_STATUS_RESERVE      0x20000000
#define JOB_STATUS_MIG          0x40000000

#define MASK_QP_JOB_STATUS      0x000FFFFF
#define MASK_STATUS(s) ((s) & MASK_QP_JOB_STATUS)

#define  IS_JOB_PENDING(s) (((s) & JOB_STATUS_PEND) || ((s) & JOB_STATUS_PSUSP))
#define  IS_JOB_STARTED(s) (((s) & JOB_STATUS_RUN) || ((s) & JOB_STATUS_SSUSP)    \
                            || ((s) & JOB_STATUS_USUSP))
#define  IS_JOB_SUSPEND(s) (((s) & JOB_STATUS_PSUSP) || ((s) & JOB_STATUS_SSUSP)  \
                            || ((s) & JOB_STATUS_USUSP))
#define  IS_JOB_ENDED(s) (((s) & JOB_STATUS_DONE) || ((s) & JOB_STATUS_EXIT))
#define  IS_JOB_POST_DONE(s) (((s) & JOB_STATUS_PDONE) == JOB_STATUS_PDONE)
#define  IS_JOB_POST_ERR(s) (((s) & JOB_STATUS_PERR) == JOB_STATUS_PERR)

/* node status */
#define NODE_STATUS_BUSY       0x01
#define NODE_STATUS_WIND       0x02
#define NODE_STATUS_DISABLED   0x04
#define NODE_STATUS_FULL       0x10
#define NODE_STATUS_UNAVAIL    0x20
#define NODE_STATUS_EXCLUSIVE  0x40

#define IS_NODE_OK(status)       (0 == status)
#define IS_NODE_CLOSED(status)   ((status & (NODE_STATUS_WIND | NODE_STATUS_DISABLED | \
                                             NODE_STATUS_FULL)) != 0)
#define IS_NODE_BUSY(status)     ((status & NODE_STATUS_BUSY) != 0)
#define IS_NODE_UNAVAIL(status)  ((status) & NODE_STATUS_UNAVAIL)

#define EXIT_ZOMBIE         0x00000001
#define EXIT_KILL_ZOMBIE    0x00000002
#define EXIT_ZOMBIE_JOB     0x00000004
#define EXIT_RERUN          0x00000008
#define EXIT_REQUEUE        0x00000010
#define EXIT_REMOVE         0x00000020

#define GRP_RECURSIVE     0x8

/* submit job option */
#define SUBOPT_JOB_NAME       0x01
#define SUBOPT_QUEUE          0x02
#define SUBOPT_HOST           0x04
#define SUBOPT_IN_FILE        0x08
#define SUBOPT_OUT_FILE       0x10
#define SUBOPT_ERR_FILE       0x20
#define SUBOPT_EXCLUSIVE      0x40
#define SUBOPT_NOTIFY_END     0x80
#define SUBOPT_NOTIFY_BEGIN   0x100
#define SUBOPT_USER_GROUP     0x200
#define SUBOPT_CHKPNT_PERIOD  0x400
#define SUBOPT_CHKPNT_DIR     0x800
#define SUBOPT_CHKPNTABLE     SUB_CHKPNT_DIR
#define SUBOPT_LOGIN_SHELL    0x1000
#define SUBOPT_RESTART        0x2000
#define SUBOPT_RERUNNABLE     0x4000
#define SUBOPT_WINDOW_SIG     0x8000
#define SUBOPT_DEPEND_COND    0x20000
#define SUBOPT_RES_REQ        0x40000
#define SUBOPT_OTHER_FILES    0x80000
#define SUBOPT_PRE_EXEC       0x100000
#define SUBOPT_POST_EXEC      0x200000
#define SUBOPT_MAIL_USER      0x400000
#define SUBOPT_MODIFY         0x800000
#define SUBOPT_JOB_PRIORITY   0x1000000
#define SUBOPT_PROJECT_NAME   0x2000000
#define SUBOPT_GPU            0x4000000
#define SUBOPT_JOB_GROUP      0x8000000
#define SUBOPT_NOFORK         0x10000000
#define SUBOPT_X_DISPLAY      0x20000000
#define SUBOPT_UNIT_KB        0x40000000
/* end for sub option */

/* start for sub option2*/
#define SUBOPT2_HOLD              0x01
#define SUBOPT2_MODIFY_CMD        0x02
#define SUBOPT2_BLOCK             0x04
#define SUBOPT2_QUEUE_RERUNNABLE  0x08
#define SUBOPT2_DEF_PROCLIMIT     0x10
#define SUBOPT2_MODIFY_RUN_JOB    0x20
#define SUBOPT2_MODIFY_PEND_JOB   0x40
#define SUBOPT2_CWD               0x80
#define SUBOPT2_REQUEUE_EXITCODE  0x100

#define RECORD_TYPE_JOB_NEW           1
#define RECORD_TYPE_JOB_START         2
#define RECORD_TYPE_JOB_STATUS        3
#define RECORD_TYPE_JOB_SWITCH        4
#define RECORD_TYPE_JOB_MOVE          5
#define RECORD_TYPE_QUEUE_CTRL        6
#define RECORD_TYPE_HOST_CTRL         7
#define RECORD_TYPE_JS_DIE            8
#define RECORD_TYPE_JOB_UNFULFILL     9
#define RECORD_TYPE_JOB_FINISH       10
#define RECORD_TYPE_TRAINING_RESULT  11
#define RECORD_TYPE_JOB_MIGRATE      12
#define RECORD_TYPE_PRE_EXEC_START   13
#define RECORD_TYPE_JS_START         14
#define RECORD_TYPE_JOB_ACCT         15
#define RECORD_TYPE_JOB_SIGNAL       16
#define RECORD_TYPE_JOB_EXECUTE      17
#define RECORD_TYPE_JOB_MSG          18
#define RECORD_TYPE_JOB_REQUEUE      19
#define RECORD_TYPE_JOB_SIGACT       20
#define RECORD_TYPE_JM_JOB_STATUS    21
#define RECORD_TYPE_JOB_START_ACCEPT 22
#define RECORD_TYPE_JOB_CLEAN        23
#define RECORD_TYPE_JOB_FORCE        24
#define RECORD_TYPE_LOG_SWITCH       25
#define RECORD_TYPE_JOB_MODIFY       26
#define RECORD_TYPE_NEW_JGRP         27
#define RECORD_TYPE_DEL_JGRP         28
#define RECORD_TYPE_MOD_JGRP         29
#define RECORD_TYPE_ADDNODE          33
#define RECORD_TYPE_DELNODE          34

#define STR_FUNC_FAIL ("%s: %s() failed.")
#define STR_FUNC_FAIL_S ("%s: %s() failed, %s.")
#define STR_FUNC_FAIL_M ("%s: %s() failed due to %m.")
#define STR_FUNC_S_FAIL ("%s: %s(%s) failed.")
#define STR_FUNC_S_FAIL_M ("%s: %s(%s) failed due to %m.")
#define STR_FUNC_D_FAIL ("%s: %s(%d) failed.")
#define STR_FUNC_D_FAIL_M ("%s: %s(%ld) failed due to %m.")
#define STR_FUNC_S_S_FAIL_M ("%s: %s(%s, %s) failed due to %m.")
#define STR_FUNC_S_S_FAIL_S ("%s(%s) failed: %s.")
#define STR_FUNC_S_D_FAIL_M ("%s: %s(%s, %d) failed due to %m.")
#define STR_FUNC_D_D_FAIL_M ("%s: %s(%d, %d) failed due to %m.")

#define STR_JOB_FAIL_S ("%s: Job <%s> failed in %s().")
#define STR_JOB_FAIL_S_S ("%s: Job <%s> failed in %s(%s).")
#define STR_JOB_FAIL_S_M ("%s: Job <%s> failed in %s() due to %m.")
#define STR_JOB_FAIL_S_S_M ("%s: Job <%s> failed in %s(%s) due to %m.")
#define STR_JOB_FAIL_S_D_M ("%s: Job <%s> failed in %s(%d) due to %m.")

/* Reason bits for queue */
#define SUSPEND_REASON_USER_STOP    0x001
#define SUSPEND_REASON_USER_RESUME  0x002
#define SUSPEND_REASON_QUEUE_WINDOW 0x004
#define SUSPEND_REASON_PREEMPTED    0x008
#define SUSPEND_REASON_LOADSTOP     0x010
#define SUSPEND_REASON_STOPCOND     0x020
#define SUSPEND_REASON_RESUMECOND   0x040
#define SUSPEND_REASON_NODEUNAVAIL  0x080
#define SUSPEND_REASON_RESOURCE     0x100
#define SUSPEND_REASON_JSLOCK       0x200 // internal used
#define SUSPEND_REASON_RESLIMIT     0x400
#define SUSPEND_REASON_JMSTART      0x800

/* unified GPU compute mode */
#define GPU_COMPUTEMODE_DEFAULT 0
#define GPU_COMPUTEMODE_EXCLUSIVE 1
#define GPU_COMPUTEMODE_PROHIBITED 2
#define GPU_COMPUTEMODE_COUNT 3

extern char *gstrTmpDir; //defined in initparams.c

#ifdef HAVE_UNION_WAIT
# define STATUS_WAIT_T      union wait
# define JOB_WSTATUS(s)   ((s).w_status)
#else
# define STATUS_WAIT_T      int
# define JOB_WSTATUS(s)   (s)
#endif

#define QUICKPOOL_SIGNAL_NULL       -65535
#define QUICKPOOL_SIGCHKPNT             -1
#define QUICKPOOL_SIGSTOP_USER          -2
#define QUICKPOOL_SIGSTOP_LOAD          -3
#define QUICKPOOL_SIGSTOP_PREEMPT       -4
#define QUICKPOOL_SIGSTOP_WINDOW        -5
#define QUICKPOOL_SIGSTOP_OTHER         -6
#define QUICKPOOL_SIGCONT_USER          -7
#define QUICKPOOL_SIGCONT_LOAD          -8
#define QUICKPOOL_SIGCONT_WINDOW        -9
#define QUICKPOOL_SIGCONT_OTHER        -10
#define QUICKPOOL_SIGKILL_USER         -11
#define QUICKPOOL_SIGKILL_OTHER        -12
#define QUICKPOOL_SIGKILL_RUNLIMIT     -13
#define QUICKPOOL_SIGKILL_DEADLINE     -14
#define QUICKPOOL_SIGKILL_PROCESSLIMIT -15
#define QUICKPOOL_SIGKILL_FORCE        -16
#define QUICKPOOL_SIGKILL_REQUEUE      -17
#define QUICKPOOL_SIGKILL_CPULIMIT     -18
#define QUICKPOOL_SIGKILL_MEMLIMIT     -19
#define QUICKPOOL_SIGKILL_SWAPLIMIT    -20
#define QUICKPOOL_SIGNAL_NUMBER         20

#define QP_JOBID(array_jobid, array_idx)               \
    (((unsigned long long)array_idx << 32) | array_jobid)

#define RESOURCE_LIMIT_NUM  11

extern int *gf_quickpool_errno(void);
#define quickpool_errno (*gf_quickpool_errno())

struct jobrequeue {
    JOBID_T jobid;
    int status;
    int options;
};

typedef enum {
    QUEUE_OPEN = 1,
    QUEUE_CLOSED,
    QUEUE_ACTIVATE,
    QUEUE_INACTIVATE,
    QUEUE_NODEADD,
    QUEUE_NODEREMOVE,
    QUEUE_NODEUPDATE,
} queue_operate_t;

typedef enum {
    HOST_OPEN = 1,
    HOST_CLOSE,
    HOST_REBOOT,
    HOST_SHUTDOWN,
} host_operate_t;

typedef enum {
    JS_DEBUG = 1,
    JS_TIMING,
} debug_request_t;

typedef enum {
    DAEMON_QUIT_INIT = 255,
    DAEMON_QUIT_MEM = 254,
    DAEMON_SHUTDOWN = 253,
    DAEMON_QUIT_RECONFIG = 252,
    DAEMON_QUIT_RESTART = 251,
    DAEMON_QUIT_FATAL = 250,
    DAEMON_QUIT_CONFFILE = 249,
    JS_QUIT_RESIGN = 248,
    JS_QUIT_RECFILE = 247,
    JM_QUIT_LOCKFILE = 246,
    DAEMON_QUIT_LICENSE = 245,
} js_quit_t;

typedef enum {
    /* Job reasons */
    REASON_NOT_SCHEDULE = 1,
    REASON_BEGIN_TIME,
    REASON_DEPENDENCY,
    REASON_DEPENDENCY_SATISFIED ,
    REASON_DEPENDENCY_SYNTAX,
    REASON_MIGRATING,
    REASON_PRESCRIPT,
    REASON_SWITCHING,
    REASON_MODIFIED,
    REASON_REQUEUED,
    REASON_AUTO_REQUEUE,
    REASON_SCHEDULE_POSTPONE,
    REASON_PREEMPTED_RESUME,
    REASON_ARRAYJOB_LIMIT,
    REASON_JOBGROUP_LIMIT,
    REASON_JOB_PTILE,
    REASON_REQUEUE_LIMIT,
    REASON_SUBMIT_SELECT,
    REASON_TERMINATE_TIME,
    REASON_SPAN_REQUIREMENT,
    REASON_ZOMBIE_JOB = 21,

    /* Queue reasons */
    REASON_QUEUE_INACTIVE = 101,
    REASON_QUEUE_RUNWINDOW,
    REASON_QUEUE_PRESCRIPT,
    REASON_QUEUE_SLOT_LIMIT,
    REASON_QUEUE_FREE_SLOT,
    REASON_QUEUE_USER_FREE_SLOT,
    REASON_QUEUE_PROCESSOR_LIMIT,
    REASON_QUEUE_NODE_SLOT_LIMIT,
    REASON_QUEUE_PTILE,
    REASON_QUEUE_NODE_MEMBER,
    REASON_QUEUE_SELECT,
    REASON_QUEUE_RUNWINDOW_CLOSE,
    REASON_QUEUE_SPAN_REQUIREMENT = 113,

    /* User reasons */
    REASON_USER_STOP = 201,
    REASON_USER_RESUME,
    REASON_USER_SLOT_LIMIT,
    REASON_USER_FREE_SLOT,
    REASON_USERGROUP_SLOT_LIMIT,
    REASON_USERGROUP_FREE_SLOT = 206,

    /* Host reasons */
    REASON_NODE_UNAVAIL = 301,
    REASON_NODE_ADMIN_CLOSED,
    REASON_NODE_DISPWINDOW,
    REASON_NODE_HAS_JOB,
    REASON_NODE_EXCLUSIVE,
    REASON_NODE_POWERED_OFF,
    REASON_NODE_TYPE,
    REASON_NODE_GPU_NUM,
    REASON_NODE_GPU_READYNUM,
    REASON_NODE_GPU_EXCLUSIVE,
    REASON_NODE_GPU_MEMORY,
    REASON_NODE_GPU_MODEL,
    REASON_NODE_WITHOUT_GPU,
    REASON_NODE_INTERVAL,
    REASON_NODE_DATASET,
    REASON_NODE_NUMABIND,
    REASON_FIRST_NODE,
    REASON_NODE_FREE_SLOT,
    REASON_NODE_SLOT_LIMIT,
    REASON_NODE_USER_SLOT_LIMIT,
    REASON_JM_FORK,
    REASON_JM_USER_ACCOUNT,
    REASON_JM_SETUP_DIR,
    REASON_JM_CREATE_JOBFILE,
    REASON_JM_EXECSCRIPT,
    REASON_JM_CHKPNT_DIR,
    REASON_JM_SYSCALL,
    REASON_JM_RESTART_JOBPID,
    REASON_JM_NO_MEM,
    REASON_JM_XDR_ERROR,
    REASON_JM_ARGUMENT = 334,

    /* Resource reasons */
    REASON_NODE_LOAD = 401,
    REASON_QUEUE_RUSAGE = 1001,
    REASON_SUBMIT_RUSAGE = 3001,
} pending_reason_t;

typedef enum {
    SUBREASON_RUNTIME = 1,
    SUBREASON_DEADLINE,
    SUBREASON_PROCESS,
    SUBREASON_CPUTIME,
    SUBREASON_MEMORY,
} suspend_subreason_t;

/* command parameters, used by qp command */
typedef enum {
    CMD_CONFDIR,
    DEBUG_CMD,
    TIMEDEBUG_CMD,
    CMD_WORKDIR,
    CMD_SHAREDIR,
    CMD_SERVERDIR,
    MASTER_LIST,
    JM_PORT,
    JS_PORT,
    CMD_LOGDIR,
    CMD_LOGMASK,
    API_CONNTIMEOUT,
    API_RECVTIMEOUT,
    API_QUOTE_CMD,
    AUTH_KIND,
    CONNECT_RETRY,
} commandparams_t;

#define EXACT         0x01
#define NORMALIZE     0x04
#define LOCAL_ONLY    0x08
#define DFT_FROMTYPE  0x40
#define ALL_CLUSTERS  0x80

#define FROM_JS   0x01

enum param_type
{
    INT_PARAM,
    BOOL_PARAM,
    STRING_PARAM,
    FLOAT_PARAM,
};

struct config_param {
    const char *param_name;     /**< Name of the parameter */
    enum param_type param_type; /**< Type of value: int, bool, string or float */
    int index;                  /**< Parameter index, -1 if parameter is not set. */
    union {
      char *string_value;
      bool_t bool_value;
      int int_value;
      double float_value;
    };
};
extern struct config_param commandParams[];

struct quickpoolInfo {
    unsigned int num_resources;
    struct resource_definition *resource_table;
    unsigned int num_types;
    char host_types[MAXTYPES][MAXNAMELEN+1];
    unsigned int num_models;
    char host_models[MAXMODELS][MAXNAMELEN+1];
    char host_archs[MAXMODELS][MAXNAMELEN+1];
    float cpu_factor[MAXMODELS];
    unsigned int num_index;
    unsigned int num_user_index;
    unsigned int bool_start_index;
    unsigned int string_start_index;
};

struct QuickPoolUserReply {
    unsigned int num_user;
    struct QuickPoolUserInfo *users;
    char error_message[MAXMESSAGELENGTH];
};

struct QuickPoolUserInfo {
    char *user;
    unsigned int max_num_slot;
    unsigned int num_job_slot;
    unsigned int num_pending_slot;
    unsigned int num_running_slot;
    unsigned int num_SSUSP_slot;
    unsigned int num_USUSP_slot;
    unsigned int num_reserving_slot;
};

struct QuickPoolUserGroupReply {
    unsigned int num_groups;
    struct QuickPoolUserGroupInfo *groups;
    char error_message[MAXMESSAGELENGTH];
};

struct QuickPoolUserGroupInfo {
    char *group_name;
    struct nameList *member_list;
    char *user_shares;
    char *exclude_members;
};

struct QuickPoolHostGroupReply {
    unsigned int num_groups;
    struct QuickPoolHostGroupInfo *groups;
    char error_message[MAXMESSAGELENGTH];
};

struct QuickPoolHostGroupInfo {
    char *group_name;
    struct nameList *member_list;
    char *exclude_members;
    unsigned int max_slots;
};

struct QuickPoolQueueReply {
    unsigned int num_queue;
    struct QuickPoolQueueInfo *queues;
    char error_message[MAXMESSAGELENGTH];
};

struct QuickPoolQueueInfo {
    char *queue;
    char *description;
    int priority;
    short nice;
    char *users;
    char *hosts;
    float *load_schedule;
    float *load_stop;
    unsigned int user_slot_limit;
    unsigned int host_slot_limit;
    unsigned int job_slot_limit;
    unsigned int min_job_slot;
    unsigned int default_job_slot;
    int schedule_policy;
    int queue_status;
    unsigned int max_num_slot;
    unsigned int num_job_slot;
    unsigned int num_pending_slot;
    unsigned int num_running_slot;
    unsigned int num_SSUSP_slot;
    unsigned int num_USUSP_slot;
    unsigned int num_reserving_slot;
    int mig;
    int job_schedule_delay;
    int job_dispatch_interval;
    char *run_window;
    char *dispatch_window;
    char *administrators;
    char *prejob_command;
    char *postjob_command;
    char *prepost_user;
    char *requeue_exitcode;
    char *resource_requirement;
    int reservation_time;
    char *resume_condition;
    char *stop_condition;
    char *job_starter;
    char *suspend_command;
    char *resume_command;
    char *terminate_command;
    int quickpool_signal[QUICKPOOL_SIGNAL_NUMBER];
    int default_ulimit[RESOURCE_LIMIT_NUM];
    int queue_ulimit[RESOURCE_LIMIT_NUM];
    char *fairshare;
    unsigned int num_fairshare_account;
    uint32_t num_fairshare_slot;      /* number of share accounts */
    struct share_acct **fairshare_accounts; /* array of share accts */
    char *preemption;
    char *ownership;          /* queue slots ownership */
    uint32_t loan_duration;   /* loan resources duration */
    uint32_t num_owned_slots; /* number of owned slots */
    char *chkpnt_dir;
    int chkpnt_period;
};

struct QuickPoolPeekReply {
    char *output_file;
    char error_message[MAXMESSAGELENGTH];
};

struct hostGPUList {    
    int gpu_id; 
    char *gpu_model;
    double gpu_maxmem; 
    float gpu_factor;
};

struct hostGPULoad {
    int gpu_id;
    int gpu_mode;
    char *status;
    double avail_gpu_mem; 
    unsigned int gpu_temperature;
    float gpu_ut;
    int num_job;
    JOBID_T *jobids;
    char *error;
};

struct QuickPoolHostReply {
    unsigned int num_hosts;
    struct QuickPoolHostInfo  *hosts;
    char error_message[MAXMESSAGELENGTH];
};

typedef enum serverFlag {
    STATIC_SERVER = 1,
    DYNAMIC_SERVER = 2,
    CLIENT = 3,
} server_t;

struct QuickPoolHostInfo {
    char *host;
    char *host_type;
    char *host_model;
    int status;
    int *jm_status;
    double *load_threshold;
    int *busy_schedule;
    int *busy_stop;
    int ncpus;
    double maxmem;
    double maxswap;
    double maxtmp;
    int *res_bitmap;
#define HOSTINFO_JM_INFO           0x01
    int flags;
    char *dispatch_window;
    char *run_window;
    float *load_schedule;
    float *load_stop;
    double *load;
    double *real_load;
    server_t server;
    unsigned int user_slot_limit;
    int max_jobs;
    unsigned int num_job_slot;
    unsigned int num_running_slot;
    unsigned int num_SSUSP_slot;
    unsigned int num_USUSP_slot;
    unsigned int num_reserving_slot;
    int mig;
    int attr;
    unsigned int num_GPU;
    struct hostGPUList *gpuinfo_static;
    struct hostGPULoad *gpuinfo_dynamic;
    struct numa_obj *numa;
};

struct QuickPoolSubmitReply {
    JOBID_T jobid;
    char *queue;
    char error_message[MAXMESSAGELENGTH];
};

/* Job group counters
 */
typedef enum {
    JGRP_COUNT_NJOBS,
    JGRP_COUNT_PEND,
    JGRP_COUNT_NPSUSP,
    JGRP_COUNT_NRUN,
    JGRP_COUNT_NSSUSP,
    JGRP_COUNT_NUSUSP,
    JGRP_COUNT_NEXIT,
    JGRP_COUNT_NDONE,
    NUM_JGRP_COUNTERS
} jgrp_count_t;

struct QuickPoolJobGroupReply {
    unsigned int num_jobgroup;
    struct QuickPoolJobGroup *job_groups;
};

struct QuickPoolJobGroup {
    char *name;
    char *path;
    int counts[NUM_JGRP_COUNTERS + 1];
    int max_jobs;
};

#define NODE_ISBUSYON(status, index)                                      \
    (((status[1 + (index)/INTEGER_BITS]) & (1 << (index)%INTEGER_BITS)) != 0)
#define STATUS_ISOK(status)  ((status[0] & NRM_OK_MASK) == 0)

struct QuickPoolHostGPUload {
    unsigned int num_GPU;
    int *gpu_mode;
    int *gpu_id;
    int *gpu_temperature;
    double *avail_gpu_mem;
    float *gpu_ut;
    char **status;
};
struct QuickPoolHostLoad {
    char *host_name;
    int *status;
    double *load_values;
    struct QuickPoolHostGPUload *gpu_load;
};

struct QuickPoolHostLoadReply {
    unsigned int num_hosts;
    unsigned int num_index;
    char **indicies;
    struct QuickPoolHostLoad *host_load;    
    char error_message[MAXMESSAGELENGTH];
};

#define QP_CHKPNT_KILL  0x1
#define QP_CHKPNT_FORCE 0x2
#define QP_CHKPNT_COPY  0x3
#define QP_CHKPNT_MIG   0x4
#define QP_CHKPNT_STOP  0x8

#define ALL_QUEUE       0x01
#define CHECK_HOST      0x02
#define CHECK_USER      0x04

#define ALL_JOB         0x00001
#define DONE_JOB        0x00002
#define PEND_JOB        0x00004
#define SUSP_JOB        0x00008
#define EXIT_JOB        0x00010
#define CUR_JOB         0x00020
#define RUN_JOB         0x00040
#define JOBID_ONLY      0x00080
#define HOST_NAME       0x00100
#define FINISH_JOB_ONCE 0x00800
#define JGRP_ARRAY_INFO 0x01000
#define GPU_JOB         0x04000

#define CLUST_STAT_OK             0x01
#define CLUST_STAT_UNAVAIL        0x02

struct QuickPoolClusterInfo {
    char cluster_name[MAXNAMELEN];
    char master_name[MAXHOSTNAMELEN];
    char manager_name[MAXNAMELEN];
    unsigned int manager_id;
    int status;
    int num_servers;
    int num_clients;
    unsigned int num_admins;
    uid_t *admin_ids;
    char **admins;
    unsigned int num_resources;
    char **resource_names;
    unsigned int num_types;
    char **host_types;
    unsigned int num_models;
    char **host_models;
};

struct QuickPoolClusterReply {
    unsigned int num_clusters;
    struct QuickPoolClusterInfo *clusters;
    char error_message[MAXMESSAGELENGTH];
};

struct QuickPoolJobDep {
    char *dependency;
    char *jobid;
    int jstatus;
    int depstatus;
};

struct QuickPoolJobDepReply {
    unsigned int num_dependency;
    struct QuickPoolJobDep *dependencies;
    char error_message[MAXMESSAGELENGTH];
};

struct pidInfo {
    pid_t pid;
    pid_t ppid;
    pid_t pgid;
};

struct jobResourceUsage {
    long mem;
    long swap;
    long utime;
    long stime;
    unsigned int npids;
    struct pidInfo *pidinfo;
    unsigned int npgids;
    pid_t *pgid;
};

#define    JS_DEBUG         1
#define    JS_TIMING        2
#define    JM_DEBUG         3
#define    JM_TIMING        4
#define    EE_DEBUG         5
#define    EE_TIMING        6

struct QuickPoolResourceReply {
    unsigned int num_resources;
    struct QuickPoolResourceInfo *resources;
    char error_message[MAXMESSAGELENGTH];
};

struct QuickPoolResourceMap {
    char *total_value;
    char *reserve_value;
    unsigned int num_hosts;
    char **hosts;
};

struct QuickPoolResourceInfo {
    char *resource_name;
    unsigned int flags;
    unsigned int num_instances;
    struct QuickPoolResourceMap *instances;
};

struct QuickPoolJobMsg {
    time_t post_time;
    char *message;
};

struct QuickPoolJobMsgReply {
    unsigned int num_message;
    struct QuickPoolJobMsg *messages;
    char error_message[MAXMESSAGELENGTH];
};

struct jobHostUsedcore{
    LIST_T *used_numa;
};

struct jobInfoNuma {
    int same;
    int exclusive;
    int num_bind;
    int bind_type;
    int cpu_bind_type;
    int mem_bind_type; 
    struct jobHostUsedcore *alloc_job_numa;
};

struct gpuInfo {
    char *model;
    int index;
    double alloc_mem;
    float factor;
};

struct jobHostGPUinfo {
    unsigned int num_gpu;
    struct gpuInfo *gpus;
};

struct jobInfoGPU {
    int exclusive;
    struct jobHostGPUinfo *alloc_job_gpu;
};

struct QuickPoolJobInfo {
    JOBID_T jobid;
    int status;
    unsigned int num_pending_reason;
    int *pending_reasons;
    int reason_id;
    int reason_detail;
    time_t start_time;
    time_t reserving_time;
    time_t possible_start;
    time_t end_time;
    float used_cpu_time;
    unsigned int *num_slot;
    unsigned int num_execute_node;
    char **execute_nodes;
    struct jobResourceUsage *resource_usage;
    float *load_schedule;
    float *load_stop;
    struct submitRequest *submit;
    int exit_stat;
    char *execute_homedir;
    char *execute_cwd;
    char *execute_user;
    time_t usage_update_time;
    int job_type;
    int counter[NUM_JGRP_COUNTERS];
    u_short port;
    int job_priority;
    struct jobInfoGPU *job_GPU;
    struct jobInfoNuma *job_numa;
    long max_mem;
    long max_swap;
};

struct QuickPoolJobReply {
    unsigned int num_job;
    JOBID_T *jobIDs;
    unsigned int num_node;
    char **node_names;
    unsigned int num_error;
    char **error_messages;
};

#define CONF_EXPAND             0X02
#define CONF_RETURN_HOSTSPEC    0X04
#define CONF_NO_EXPAND          0X08

struct QuickPoolParameter {
    unsigned int number;
    struct config_param *param;
};

struct QuickPoolFileCopyReply {
    int num_buf;
    char **file_buffer;
};

struct userConf {
    unsigned int num_users;
    struct QuickPoolUserInfo *users;
    unsigned int num_user_groups;
    struct QuickPoolUserGroupInfo *user_groups;
};

struct hostConf {
    unsigned int num_hosts;
    struct QuickPoolHostInfo *hosts;
    unsigned int num_host_groups;
    struct QuickPoolHostGroupInfo *host_groups;
};

struct  resourceLoc {
    char *resource_name;
    char *location;
};

struct clusterConf {
    unsigned int num_hosts;
    struct QuickPoolHostInfo *hosts;
    struct admins *admin;
    struct config_param *param;
    unsigned int num_location;
    struct resourceLoc *loc;
};

struct sharedConf {
    struct quickpoolInfo *qpinfo;
    char *cluster_name;
    char *servers;
};

struct queueConf {
    unsigned int num_queues;
    struct QuickPoolQueueInfo *queues;
};

struct execution_file {
    char in_file[PATH_MAX+1];
    char out_file[PATH_MAX+1];
    unsigned int direction;
#define  XF_OP_SUB2EXEC         0x1
#define  XF_OP_EXEC2SUB         0x2
#define  XF_OP_SUB2EXEC_APPEND  0x4
#define  XF_OP_EXEC2SUB_APPEND  0x8
};

#define RECORD_KEY_JOBID              1
#define RECORD_KEY_USERID             2
#define RECORD_KEY_OPTIONS            3
#define RECORD_KEY_OPTIONS2           4
#define RECORD_KEY_PROCESSOR          5
#define RECORD_KEY_MAX_PROCESSOR      6
#define RECORD_KEY_SUBMIT_TIME        7
#define RECORD_KEY_BEGIN_TIME         8
#define RECORD_KEY_TERMINATE_TIME     9
#define RECORD_KEY_USERNAME          10
#define RECORD_KEY_SCHEDULE_HOSTTYPE 11
#define RECORD_KEY_LOGIN_SHELL       12
#define RECORD_KEY_SIGNAL            13
#define RECORD_KEY_RESTART_PID       14
#define RECORD_KEY_LIMIT_CPU         15
#define RECORD_KEY_LIMIT_FSIZE       16
#define RECORD_KEY_LIMIT_DATA        17
#define RECORD_KEY_LIMIT_STACK       18
#define RECORD_KEY_LIMIT_CORE        19
#define RECORD_KEY_LIMIT_RSS         20
#define RECORD_KEY_LIMIT_NOFILE      21
#define RECORD_KEY_LIMIT_OPEN_MAX    22
#define RECORD_KEY_LIMIT_SWAP        23
#define RECORD_KEY_LIMIT_RUN         24
#define RECORD_KEY_LIMIT_PROCESS     25
#define RECORD_KEY_NODE_RANK         26
#define RECORD_KEY_POSTEXEC          27
#define RECORD_KEY_UMASK             28
#define RECORD_KEY_QUEUE             29
#define RECORD_KEY_RESREQ            30
#define RECORD_KEY_FROM_HOST         31
#define RECORD_KEY_CWD               32
#define RECORD_KEY_SUBMIT_HOMEDIR    33
#define RECORD_KEY_SUBMIT_INFILE     34
#define RECORD_KEY_SUBMIT_OUTFILE    35
#define RECORD_KEY_SUBMIT_ERRFILE    36
#define RECORD_KEY_JOB_FILE          40
#define RECORD_KEY_NUM_ASKEDHOST     41
#define RECORD_KEY_ASKEDHOST         42
#define RECORD_KEY_JOB_NAME          43
#define RECORD_KEY_COMMAND           44
#define RECORD_KEY_DEPENDENCY        45
#define RECORD_KEY_PREEXEC           46
#define RECORD_KEY_MAIL_USER         47
#define RECORD_KEY_PROJECT_NAME      48
#define RECORD_KEY_NUM_XFILE         49
#define RECORD_KEY_XFILE             50
#define RECORD_KEY_USER_PRIORITY     51
#define RECORD_KEY_USER_GROUP        52
#define RECORD_KEY_ABS_RUN_LIMIT     53
#define RECORD_KEY_JOB_GROUP         54
#define RECORD_KEY_CHECKPOINT_DIR    55
#define RECORD_KEY_CHECKPOINT_METHOD 56
#define RECORD_KEY_CHECKPOINT_PERIOD 57
#define RECORD_KEY_JOB_STATUS        58
#define RECORD_KEY_JOB_FLAG          59
#define RECORD_KEY_NUM_EXECHOST      60
#define RECORD_KEY_EXECHOST          61
#define RECORD_KEY_JOB_PID           62
#define RECORD_KEY_JOB_PGID          63
#define RECORD_KEY_QUEUE_PRECMD      64
#define RECORD_KEY_QUEUE_POSTCMD     65
#define RECORD_KEY_EXEC_HOME         66
#define RECORD_KEY_EXEC_CWD          67
#define RECORD_KEY_EXEC_USERNAME     68
#define RECORD_KEY_JOB_CPUTIME       69
#define RECORD_KEY_JOB_ENDTIME       70
#define RECORD_KEY_NEW_REASON        71
#define RECORD_KEY_SUSP_REASON       72
#define RECORD_KEY_JOB_EXITCODE      73
#define RECORD_KEY_NUM_TASK          74
#define RECORD_KEY_START_TIME        75
#define RECORD_KEY_END_TIME          76
#define RECORD_KEY_USAGE_MEM         77
#define RECORD_KEY_USAGE_SWAP        78
#define RECORD_KEY_MANAGER_NODE      79
#define RECORD_KEY_CLUSTER_NAME      80
#define RECORD_KEY_HOST_NAME         81
#define RECORD_KEY_HOST_MODEL        82
#define RECORD_KEY_HOST_TYPE         83
#define RECORD_KEY_RCV               84
#define RECORD_KEY_NUM_ALLOC_SLOT    86
#define RECORD_KEY_NUM_BUSYTHRESHOLD 87
#define RECORD_KEY_BUSYTHRESHOLD     88
#define RECORD_KEY_NUM_RESOURCE      89
#define RECORD_KEY_RESOURCE          90
#define RECORD_KEY_PRIORITY          91
#define RECORD_KEY_RUN_WINDOW        92
#define RECORD_KEY_DISPATCH_WINDOW   93
#define RECORD_KEY_MODIFY_JOBIDS     94
#define RECORD_KEY_DELETE_OPTIONS    95
#define RECORD_KEY_DELETE_OPTIONS2   96
#define RECORD_KEY_GPU_NUM           97
#define RECORD_KEY_GPU_MODEL         98
#define RECORD_KEY_GPU_EXCLUSIVE     99
#define RECORD_KEY_GPU_MEM          100
#define RECORD_KEY_GPU_MPS          101
#define RECORD_KEY_JOB_REASON       102
#define RECORD_KEY_JOB_SUBREASON    103
#define RECORD_KEY_JOB_ACTPID       104
#define RECORD_KEY_JOB_ACTVALUE     105
#define RECORD_KEY_JOB_ACTFLAG      106
#define RECORD_KEY_JOB_ACTSTATUS    107
#define RECORD_KEY_JOB_ACTREASON    108
#define RECORD_KEY_JOB_ACTSUBREASON 109
#define RECORD_KEY_POSITION         110
#define RECORD_KEY_REQCODE          111
#define RECORD_KEY_JOB_MESSAGE      112
#define RECORD_KEY_SIGNAL_SYMBOL    113
#define RECORD_KEY_SIGNAL_COUNT     114
#define RECORD_KEY_PORT             115
#define RECORD_KEY_JOBGROUP_NAME    116
#define RECORD_KEY_JOBGROUP_PATH    117
#define RECORD_KEY_JOBGROUP_SUBTIME 118
#define RECORD_KEY_JOBGROUP_MAXJOB  119
#define RECORD_KEY_NUM_QUEUE        120
#define RECORD_KEY_NUM_HOST         121
#define RECORD_KEY_NUM_REMOVEJOB    122
#define RECORD_KEY_EXIT_CODE        123
#define RECORD_KEY_SWITCH_FLAG      124
#define RECORD_KEY_MODIFY_FLAG      125
#define RECORD_KEY_PEND_SIGNAL      126
#define RECORD_KEY_PEND_SIGNAL1     127
#define RECORD_KEY_PEND_SIGNALFLAG  128
#define RECORD_KEY_NUM_INDEX        129
#define RECORD_KEY_INDEX            130
#define RECORD_KEY_JOB_RUNTIME      133
#define RECORD_KEY_REQUEUE_EXITCODE  135
#define RECORD_KEY_MAX_MEM          136
#define RECORD_KEY_MAX_SWAP         137
#define RECORD_KEY_TASK_STATUS      138
#define RECORD_KEY_USAGE_UTIME      139
#define RECORD_KEY_USAGE_STIME      140
#define RECORD_KEY_USAGE_NPID       141
#define RECORD_KEY_USAGE_PIDINFO    142
#define RECORD_KEY_USAGE_NPGID      143
#define RECORD_KEY_USAGE_PGID       144

struct record {
    char version[MAXVERSIONLEN];
    int type;
    time_t log_time;
    unsigned int numKVs;
    key_value_t *KVs;
};

struct recordFileHandle {
    FILE *file_handle;
    char record_filename[PATH_MAX+1];
    int current_fileno;
    int last_fileno;
};

struct poolMaster {
    char *master;
    unsigned int port;
    unsigned int conntimeout;
    unsigned int recvtimeout;
};

#define RUNJOB_OPT_NORMAL     0x01
#define RUNJOB_OPT_NOSTOP     0x02

struct submitRequest {
    int options;
    int options2;
    char *job_name;
    uid_t uid;
    char *user;
    char *queue;
    char *project;
    char *user_group;
    char *mail_user;
    char *job_group;
    char *from_node;
    time_t submit_time;
    unsigned int num_job_slot;
    unsigned int max_job_slot;
    char *resource_requirement;
    char *login_shell;
    char *prejob_command;
    char *postjob_command;
    unsigned int num_spec_node;
    char **spec_nodes;
    int job_ulimit[RESOURCE_LIMIT_NUM];
    char *dependency;
    time_t begin_time;
    time_t terminate_time;
    int window_signal;
    char *home_dir;
    char *input_file;
    char *output_file;
    char *error_file;
    char *command;
    char *new_command;
    unsigned int num_exec_files;
    struct execution_file *exec_files;
    char *script;
    int umask;
    char *cwd;
    int modn_options;
    int modn_options2;
    int execute_jobpid;
    char *execute_host_type;
    int spec_priority;
    char *chkpnt_dir;
    unsigned int chkpnt_duration;
    char *chkpnt_method;
    unsigned int num_gpu;
    char *gpu_model;
    int gpu_exclusive;
    double gpu_mem;
    char *gpu_mps;
    char *requeue_exitcode;
    unsigned int thread_pertask;
};

struct dynamicNode {
    LIST_T *forw;
    LIST_T *back;
    struct request *node_req;
};

/* quickpool numa represenation */
typedef enum {
    NUMA_HOST,       /* numa machine */
    NUMA_NODE,       /* memory node */
    NUMA_SOCKET,     /* processor socket */
    NUMA_CORE,       /* processor core */
} numa_type;

typedef struct numa_obj {
    struct numa_obj *forw;
    struct numa_obj *back;
    struct numa_obj *parent;
    struct numa_obj *child;
    int type;         /* numa object type */
    int total;              /* number of cores under this object*/
    int used;               /* number of used cores under this object*/
    int index;              /* index of all the meachine*/
    int index_sibling;      /* index number below the same parent */
    int bound;              /* number of bound processes */
    unsigned int child_num; /*number of child */
    int memory;               /*memory  unit is Mb*/
} numa_obj_t;

extern int gf_qp_init(const char *);
extern int init_config_param(struct config_param *, char *);

extern struct record *read_file_line(FILE *, unsigned int *);
extern void free_record(struct record *);

extern char *jobid_2longstring(JOBID_T, char[]);
extern char *jobid_2string(JOBID_T, char[]);

extern int qp_isclustername(char *);
extern char *qp_getmyhostname(void);
extern char *qp_getclustername(void);
extern char *qp_getmastername(void);
extern struct QuickPoolClusterReply *qp_clusterinfo(struct request *, struct poolMaster *);
extern struct QuickPoolHostReply *qp_gethostinfo(struct request *, struct poolMaster *);
extern struct quickpoolInfo *qp_info(struct poolMaster *);
extern struct QuickPoolResourceReply *qp_sharedresourceinfo(struct request *, struct poolMaster *);
extern struct QuickPoolHostLoadReply *qp_gethostload(struct request *, struct poolMaster *);
extern int load_dynamic_node(LIST_T *);
extern void free_dynamic_node(void *);

extern struct sharedConf *readconf_shared(char *);
extern struct clusterConf *readconf_cluster(char *);

extern struct QuickPoolJobReply *client_get_jobids(struct request *, struct poolMaster *);
extern struct QuickPoolJobInfo *client_get_jobinfo(void);
extern void client_finish_getting();

extern int client_addhost(struct request *, struct poolMaster *);
extern int client_removehost(const char *, struct poolMaster *);

extern int client_reconfig(struct request *, struct poolMaster *);
extern int client_request_debug(struct request *, char *);
extern int client_control_host(struct request *, struct poolMaster *);
extern int client_control_queue(struct request *, struct poolMaster *);
extern struct QuickPoolJobReply *client_migratejob(struct request *, struct poolMaster *);
extern int client_add_jobgroup(struct request *, struct poolMaster *);
extern int client_modify_jobgroup(struct request *, struct poolMaster *);
extern int client_remove_jobgroup(struct request *, struct poolMaster *);
extern struct QuickPoolJobGroupReply *client_get_jobgroup(struct request *, struct poolMaster *);
extern struct QuickPoolResourceReply *client_get_resourceinfo(struct request *, struct poolMaster *);
extern JOBID_T client_submit_job(struct request *, struct QuickPoolSubmitReply *, struct poolMaster *);
extern int client_modify_job(struct request *, struct QuickPoolSubmitReply *, JOBID_T, struct poolMaster *);
extern char *client_peekjob(JOBID_T);
extern int client_runjob(struct request *, struct poolMaster *);
extern int client_movejob(struct request *, struct poolMaster *);
extern struct QuickPoolJobReply *client_switchjob(struct request *, struct poolMaster *);
extern struct QuickPoolJobReply *client_signaljob(struct request *, struct poolMaster *);

extern int client_post_jobmessage(struct request *, struct poolMaster *);
extern struct QuickPoolJobMsgReply *client_read_jobmessage(struct request *, struct poolMaster *);
extern struct QuickPoolJobDepReply *client_get_jobdependency(struct request *, struct poolMaster *);

extern struct QuickPoolHostGroupReply *client_get_hostgroupinfo(struct request *, struct poolMaster *);
extern struct QuickPoolUserGroupReply *client_get_usergroupinfo(struct request *, struct poolMaster *);
extern struct QuickPoolUserReply *client_get_userinfo(struct request *, struct poolMaster *);
extern struct QuickPoolHostReply *client_get_hostinfo(struct request *, struct poolMaster *);
extern struct QuickPoolQueueReply *client_get_queueinfo(struct request *, struct poolMaster *);
extern struct QuickPoolParameter *client_get_setting(struct poolMaster *);
extern int client_copy_file(int , char *, char *, char *, char *, struct poolMaster *);
#endif
